package com.isoft.uaaservice.filter;



import com.isoft.uaaservice.bean.LoginSysUserDetails;
import com.isoft.uaaservice.bean.exp.TokenException;
import com.isoft.uaaservice.bean.exp.UserNonLoginException;
import com.isoft.uaaservice.handler.AuthenticationEntryPointImpl;
import com.isoft.uaaservice.util.JwtUtil;
import com.isoft.uaaservice.util.RedisKeyUtil;
import com.isoft.uaaservice.util.RedisUtil;
import io.jsonwebtoken.Claims;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

@Slf4j
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Autowired
    RedisUtil redisUtil;

    @Autowired
    AuthenticationEntryPointImpl authenticationEntryPoint;

    //验证码校验方法
    private boolean valiCode(HttpServletRequest request){
        //获取用户提交uuid与验证码
        String uuid = request.getParameter("uuid");
        if (null == uuid || uuid.trim().length()==0){
            return false;
        }
        String codeInClient = request.getParameter("code");
        //根据uuid从redis读取服务器存储的验证码
        String codeInServer = redisUtil.getCachObject(RedisKeyUtil.keyVerifycode(uuid),String.class);
        //是否删除redis缓存的验证码
        return codeInClient.equalsIgnoreCase(codeInServer);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

        //验证码校验，校验是有前提的 "/sys/user/logincode"
//        if ("/sys/user/logincode".equalsIgnoreCase(request.getRequestURI()) && "post".equalsIgnoreCase(request.getMethod())){
//            if(! valiCode(request)){
//                authenticationEntryPoint.commence(request , response , new VerifyCodeException("验证码错误！"));
//                return;
//            }
//        }
        //从header获取token,前台封装进header的token必须命名为token
        String token = request.getHeader("token");
        //前台请求没有携带token ，可能是允许放行的请求 == > 交给后面的filter处理
        if(null == token || token.trim().length() == 0){
            filterChain.doFilter(request, response);
            return;
        }
        //前台请求携带token,解析jwt，获取userid
        String userid = null;
        try{
            Claims claims = JwtUtil.parseJWT(token);
            userid =claims.getSubject();
        }catch (Exception e){
            log.error("token非法！");
            authenticationEntryPoint.commence(request , response,
                    new TokenException("token非法"));
            return;
        }

        //从redis获取用户信息
        LoginSysUserDetails loginSysUserDetails = redisUtil.getCachObject(RedisKeyUtil.keyLoginSysuser(userid) , LoginSysUserDetails.class);
        if (null == loginSysUserDetails){
            log.error("用户未登录！");
            authenticationEntryPoint.commence(request , response,
                    new UserNonLoginException("用户未登录！"));
            return;
        }

        //存入SecurityContext
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(loginSysUserDetails,null,loginSysUserDetails.getAuthorities());
        SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);

        //执行后面的过滤器
        filterChain.doFilter(request ,response);


    }

}
